home *** CD-ROM | disk | FTP | other *** search
/ Total Network Tools 2002 / NextStepPublishing-TotalNetworkTools2002-Win95.iso / Archive / Misc Servers / Zope.exe / ZSERVICE.PY < prev    next >
Encoding:
Text File  |  2000-06-13  |  11.5 KB  |  314 lines

  1. ##############################################################################
  2. # Zope Public License (ZPL) Version 1.0
  3. # -------------------------------------
  4. # Copyright (c) Digital Creations.  All rights reserved.
  5. # This license has been certified as Open Source(tm).
  6. # Redistribution and use in source and binary forms, with or without
  7. # modification, are permitted provided that the following conditions are
  8. # met:
  9. # 1. Redistributions in source code must retain the above copyright
  10. #    notice, this list of conditions, and the following disclaimer.
  11. # 2. Redistributions in binary form must reproduce the above copyright
  12. #    notice, this list of conditions, and the following disclaimer in
  13. #    the documentation and/or other materials provided with the
  14. #    distribution.
  15. # 3. Digital Creations requests that attribution be given to Zope
  16. #    in any manner possible. Zope includes a "Powered by Zope"
  17. #    button that is installed by default. While it is not a license
  18. #    violation to remove this button, it is requested that the
  19. #    attribution remain. A significant investment has been put
  20. #    into Zope, and this effort will continue if the Zope community
  21. #    continues to grow. This is one way to assure that growth.
  22. # 4. All advertising materials and documentation mentioning
  23. #    features derived from or use of this software must display
  24. #    the following acknowledgement:
  25. #      "This product includes software developed by Digital Creations
  26. #      for use in the Z Object Publishing Environment
  27. #      (http://www.zope.org/)."
  28. #    In the event that the product being advertised includes an
  29. #    intact Zope distribution (with copyright and license included)
  30. #    then this clause is waived.
  31. # 5. Names associated with Zope or Digital Creations must not be used to
  32. #    endorse or promote products derived from this software without
  33. #    prior written permission from Digital Creations.
  34. # 6. Modified redistributions of any form whatsoever must retain
  35. #    the following acknowledgment:
  36. #      "This product includes software developed by Digital Creations
  37. #      for use in the Z Object Publishing Environment
  38. #      (http://www.zope.org/)."
  39. #    Intact (re-)distributions of any official Zope release do not
  40. #    require an external acknowledgement.
  41. # 7. Modifications are encouraged but must be packaged separately as
  42. #    patches to official Zope releases.  Distributions that do not
  43. #    clearly separate the patches from the original work must be clearly
  44. #    labeled as unofficial distributions.  Modifications which do not
  45. #    carry the name Zope may be packaged in any form, as long as they
  46. #    conform to all of the clauses above.
  47. # Disclaimer
  48. #   THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
  49. #   EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  50. #   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  51. #   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
  52. #   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  53. #   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  54. #   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  55. #   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  56. #   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  57. #   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  58. #   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  59. #   SUCH DAMAGE.
  60. # This software consists of contributions made by Digital Creations and
  61. # many individuals on behalf of Digital Creations.  Specific
  62. # attributions are listed in the accompanying credits file.
  63. ##############################################################################
  64. """
  65. ZServer as a NT service.
  66.  
  67. The serice starts up and monitors a ZServer process.
  68.  
  69. Features:
  70.   
  71.   * When you start the service it starts ZServer
  72.   * When you stop the serivice it stops ZServer
  73.   * It monitors ZServer and restarts it if it exits abnormally
  74.   * If ZServer is shutdown from the web, the service stops.
  75.   * If ZServer cannot be restarted, the service stops.
  76.  
  77. Usage:
  78.  
  79.   Installation
  80.   
  81.     The ZServer service should be installed by the Zope Windows
  82.     installer. You can manually install, uninstall the service from
  83.     the commandline.
  84.     
  85.       ZService.py [options] install|update|remove|start [...]
  86.           |stop|restart [...]|debug [...]
  87.  
  88.     Options for 'install' and 'update' commands only:
  89.     
  90.      --username domain\username : The Username the service is to run
  91.                                   under
  92.      
  93.      --password password : The password for the username
  94.      
  95.      --startup [manual|auto|disabled] : How the service starts, 
  96.                                         default = manual
  97.   
  98.     Commands
  99.            
  100.       install : Installs the service
  101.      
  102.       update : Updates the service, use this when you change
  103.                ZServer.py
  104.      
  105.       remove : Removes the service
  106.      
  107.       start : Starts the service, this can also be done from the
  108.               services control panel
  109.      
  110.       stop : Stops the service, this can also be done from the
  111.              services control panel
  112.      
  113.       restart : Restarts the service
  114.      
  115.       debug : Runs the service in debug mode
  116.   
  117.     You can view the usage options by running ZServer.py without any
  118.     arguments.
  119.     
  120.     Note: you may have to register the Python service program first,
  121.       
  122.       win32\pythonservice.exe /register
  123.     
  124.   Starting Zope
  125.   
  126.     Start Zope by clicking the 'start' button in the services control
  127.     panel. You can set Zope to automatically start at boot time by
  128.     choosing 'Auto' startup by clicking the 'statup' button.
  129.   
  130.   Stopping Zope
  131.   
  132.     Stop Zope by clicking the 'stop' button in the services control
  133.     panel. You can also stop Zope through the web by going to the
  134.     Zope control panel and by clicking 'Shutdown'. 
  135.   
  136.   Event logging
  137.   
  138.     Zope events are logged to the NT application event log. Use the
  139.     event viewer to keep track of Zope events.
  140.  
  141.   Registry Settings
  142.   
  143.     You can change how the service starts ZServer by editing a registry
  144.     key.
  145.     
  146.       HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\
  147.         <Service Name>\Parameters\start
  148.  
  149.     The value of this key is the command which the service uses to
  150.     start ZServer. For example:
  151.     
  152.       "C:\Program Files\Zope\bin\python.exe"
  153.         "C:\Program Files\Zope\z2.py" -w 8888
  154.  
  155.     
  156. TODO:
  157.  
  158.   * Integrate it into the Windows installer.
  159.   * Add ZLOG logging in addition to event log logging.
  160.   * Make it easier to run multiple Zope services with one Zope install
  161.  
  162. This script does for NT the same sort of thing zdaemon.py does for UNIX.
  163. Requires Python win32api extensions.
  164. """
  165. import sys, os, string, time, imp
  166.  
  167. # Some fancy path footwork is required here because we
  168. # may be run from python.exe or lib/win32/PythonService.exe
  169.  
  170. home=os.path.split(os.path.split(sys.executable)[0])[0]
  171. if sys.executable[-10:]!='python.exe':
  172.     home=os.path.split(home)[0]
  173.     home=os.path.split(home)[0]
  174. sys.path.append(os.path.join(home, 'bin'))
  175. sys.path.append(os.path.join(home, 'ZServer'))
  176. sys.path.append(os.path.join(home, 'bin', 'lib', 'win32'))
  177. sys.path.append(os.path.join(home, 'bin', 'lib', 'win32', 'lib'))
  178.  
  179.  
  180. # pythoncom and pywintypes are special, and require these hacks when
  181. # we dont have a standard Python installation around.
  182.  
  183. import win32api
  184. def magic_import(modulename, filename):
  185.     # by Mark Hammond
  186.     try:
  187.         # See if it does import first!
  188.         return __import__(modulename)
  189.     except ImportError:
  190.         pass
  191.     # win32 can find the DLL name.
  192.     h = win32api.LoadLibrary(filename)
  193.     found = win32api.GetModuleFileName(h)
  194.     # Python can load the module
  195.     mod = imp.load_module(modulename, None, found, ('.dll', 'rb', imp.C_EXTENSION))
  196.     # inject it into the global module list.
  197.     sys.modules[modulename] = mod
  198.     # And finally inject it into the namespace.
  199.     globals()[modulename] = mod
  200.     win32api.FreeLibrary(h)
  201.  
  202. magic_import('pywintypes','pywintypes15.dll')
  203.  
  204. import win32serviceutil, win32service, win32event, win32process
  205. try: import servicemanager
  206. except: pass
  207.  
  208.  
  209.  
  210. class ZServerService(win32serviceutil.ServiceFramework):
  211.  
  212.     # Some trickery to determine the service name. The WISE
  213.     # installer will write an svcname.txt to the ZServer dir
  214.     # that we can use to figure out our service name.
  215.  
  216.     path=os.path.join(home, 'ZServer', 'svcname.txt')
  217.     file=open(path, 'r')
  218.     _svc_name_=string.strip(file.readline())
  219.     file.close()
  220.  
  221.     _svc_display_name_ = "Zope (%s)" % _svc_name_
  222.     
  223.     restart_min_time=5 # if ZServer restarts before this many
  224.                        # seconds then we have a problem, and
  225.                        # need to stop the service.
  226.     
  227.     def __init__(self, args):
  228.         win32serviceutil.ServiceFramework.__init__(self, args)
  229.         self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
  230.     
  231.     def SvcDoRun(self):
  232.         self.start_zserver()
  233.         while 1:
  234.             rc=win32event.WaitForMultipleObjects(
  235.                     (self.hWaitStop, self.hZServer), 0, win32event.INFINITE)
  236.             if rc - win32event.WAIT_OBJECT_0 == 0:
  237.                 break
  238.             else:
  239.                 self.restart_zserver()
  240.         self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING, 5000)   
  241.  
  242.     def SvcStop(self):
  243.         servicemanager.LogInfoMsg('Stopping Zope.') 
  244.         try:
  245.             self.stop_zserver()              
  246.         except:
  247.             pass
  248.         self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
  249.         win32event.SetEvent(self.hWaitStop)
  250.  
  251.     def start_zserver(self):
  252.         sc=self.get_start_command()
  253.         result=win32process.CreateProcess(None, self.get_start_command(),
  254.                 None, None, 0, 0, None, None, win32process.STARTUPINFO())
  255.         self.hZServer=result[0]
  256.         self.last_start_time=time.time()
  257.         servicemanager.LogInfoMsg('Starting Zope.')
  258.         
  259.     def stop_zserver(self):
  260.         win32process.TerminateProcess(self.hZServer,0)
  261.         
  262.     def restart_zserver(self):
  263.         if time.time() - self.last_start_time < self.restart_min_time:
  264.             servicemanager.LogErrorMsg('Zope died and could not be restarted.')
  265.             self.SvcStop()
  266.         code=win32process.GetExitCodeProcess(self.hZServer)
  267.         if code == 0:
  268.             # Exited with a normal status code,
  269.             # assume that shutdown is intentional.
  270.             self.SvcStop()
  271.         else:
  272.             servicemanager.LogWarningMsg('Restarting Zope.')
  273.             self.start_zserver()
  274.  
  275.     def get_start_command(self):
  276.         return win32serviceutil.GetServiceCustomOption(self,'start')
  277.         
  278.         
  279. def set_start_command(value):
  280.     "sets the ZServer start command if the start command is not already set"
  281.     current=win32serviceutil.GetServiceCustomOption(ZServerService,
  282.                                                     'start', None)
  283.     if current is None:
  284.         win32serviceutil.SetServiceCustomOption(ZServerService,'start',value)
  285.             
  286.  
  287. if __name__=='__main__':
  288.     win32serviceutil.HandleCommandLine(ZServerService)
  289.     if 'install' in sys.argv:
  290.         command='"%s" "%s" -S' % (sys.executable, os.path.join(home,'z2.py'))
  291.         set_start_command(command)
  292.         print "Setting ZServer start command to:", command
  293.